package com.qf.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;


    /**
     * 认证配置方法
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        String encode = passwordEncoder.encode("123456");
//        System.out.println(encode);
//
//        auth.inMemoryAuthentication().withUser("admin").password(encode).roles("");
        //1.指定认证过程是哪个认证类完成
        //2.指定加密器
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //自定义配置

        //1.关闭csrf跨站伪造请求
        //security认为只要不是它本身提供的页面资源，就是非法的
        http.csrf().disable();

        //2.自定义登录表单
        http.formLogin()
                .loginPage("/login.html")  //指定登录页
                .loginProcessingUrl("/user/login")  //设置登录路径
                .defaultSuccessUrl("/success")//默认登录成功跳转路径
                .permitAll(); //放行


        //4.指定放行的资源。要写在所有认证通过的请求前面
        http.authorizeRequests()
                //指定放行资源的规则
                .antMatchers("/", "/show/name", "/user/register")
                .permitAll();
        //5.基于角色控制访问权限
        http.authorizeRequests()
                //具备 student 或者 parent 这个角色才能访问 /student/** 的资源。
                .antMatchers("/student/add")
                .hasAnyRole("student","parent");//在这个API中会自动帮我们加上 ROLE_ 前缀
        //如果没有对应的角色，就无法访问到目标资源，会报 403 【权限不足】

        //6.基于权限控制访问权限
        http.authorizeRequests()
                //具备 update 权限 才能/student/update 的资源。
                .antMatchers("/student/update")
                .hasAuthority("update");

        //7.处理403
        http.exceptionHandling().accessDeniedPage("/403.html");


        //8.登出
        http.logout()
                //退出url
                .logoutUrl("/user/logout")
                //退出后去哪
                .logoutSuccessUrl("/login.html")
                //杀死session
                .invalidateHttpSession(true)
                //删除cookie
                .deleteCookies("JSESSIONID");



        //3.拦截规则【一定要指定】
        //认证通过之后全部放行（不拦截）
        http.authorizeRequests()
                //任意请求
                .anyRequest()
                //认证通过
                .authenticated();



    }
}
